package com.liu.common.util;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.liu.common.entity.MultipleSheelPropety;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.List;

@Slf4j
public class EsayExcelUtils {
    /**
     * 生成单个Sheet的excle
     *
     * @param fileName
     * @param data      数据
     * @param voClass
     * @param sheetName
     */
    public static String writeOneSheel(String fileName, List data, Class voClass, String sheetName) {
        //获取存放文件路径
        String filePath = getFilePath(fileName);
        ExcelWriter excelWriter = null;
        try {
            //EasyExcel.write(filePath, voClass).sheet(sheetName).registerWriteHandler(defaultCellStyle()).doWrite(data);
            excelWriter = EasyExcel.write(filePath, voClass).build();
            WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).registerWriteHandler(defaultCellStyle()).build();
            excelWriter.write(data, writeSheet);
        } catch (Exception e) {
            log.error("生成文件:" + fileName + "报错了。" + e.getMessage());
            e.printStackTrace();
        } finally {
            if (excelWriter != null) {
                // 千万别忘记finish 会帮忙关闭流
                excelWriter.finish();
            }
        }
        return filePath;
    }

    /**
     * 设置默认样式
     */
    public static HorizontalCellStyleStrategy defaultCellStyle() {
        // 头的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short) 12);
        headWriteCellStyle.setWriteFont(headWriteFont);
        // 内容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        WriteFont contentWriteFont = new WriteFont();
        // 字体大小
        contentWriteFont.setFontHeightInPoints((short) 11);
        contentWriteCellStyle.setWriteFont(contentWriteFont);
        // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
        return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
    }

    public static String getFilePath(String fileName) {
        //获取存放目录路径
        String fileDirPath = FileUtils.getExcelExportPath();
        //创建目录
        FileUtils.isNewFolder(fileDirPath);
        return fileDirPath + "/" + System.currentTimeMillis() + fileName;
    }


    /**
     * 默认excel文件名和单元sheet名一样的 Excel文件导出
     *
     * @param httpServletResponse
     * @param data
     * @param fileName
     * @param clazz
     * @throws IOException
     * @author guojia 2020-11-05
     */
    public static void writeExcel(HttpServletResponse httpServletResponse, List data, String fileName, Class clazz) throws IOException {
        writeExcel(httpServletResponse, data, fileName, fileName, clazz);
    }

    /**
     * 导出数据为Excel文件
     *
     * @param response  响应实体
     * @param data      导出数据
     * @param fileName  文件名
     * @param sheetName 单元格名
     * @param clazz     定义excel导出的实体
     * @throws IOException
     * @author guojia 2020-11-05
     */
    public static void writeExcel(HttpServletResponse response, List data, String fileName, String sheetName, Class clazz) throws IOException {
        //防止中文乱码
        fileName = URLEncoder.encode(fileName, "UTF-8");
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        //防止导入excel文件名中文不乱码
        response.setHeader("Content-disposition", "attachment;fileName=" + fileName + ".xlsx");
        EasyExcel.write(response.getOutputStream(), clazz).autoCloseStream(Boolean.FALSE).sheet(sheetName).doWrite(data);
    }

    /**
     * 生成多Sheet的excle
     *
     * @param fileName              文件名
     * @param multipleSheelPropetys
     */
    public static String writeMultipleSheelExcel(HttpServletResponse response,String fileName, List<MultipleSheelPropety> multipleSheelPropetys) throws IOException{
        //获取存放文件路径
        String filePath = getFilePath(fileName);
        //防止中文乱码
        fileName = URLEncoder.encode(fileName, "UTF-8");
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        //防止导入excel文件名中文不乱码
        response.setHeader("Content-disposition", "attachment;fileName=" + fileName + ".xlsx" + ";fileName*=utf-8''" + fileName + ".xlsx");
        //新建ExcelWriter
        ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();
        WriteSheet writeSheet;
        // sheet
        int sheetNo = -1;
        for (MultipleSheelPropety multipleSheelPropety : multipleSheelPropetys) {
            sheetNo++;
            // 每次都要创建writeSheet 这里注意必须指定sheetNo
            writeSheet = EasyExcel.writerSheet(sheetNo, multipleSheelPropety.getSheetName()).head(multipleSheelPropety.getVoClass()).registerWriteHandler(defaultCellStyle()).build();
            //数据 这里可以去数据库查询每一页的数据
            excelWriter.write(multipleSheelPropety.getData(), writeSheet);
        }
        // 千万别忘记finish 关闭流
        excelWriter.finish();
        return filePath;
    }

    /**
     * 生成多Sheet的excle
     *
     * @param fileName              文件名
     * @param multipleSheelPropetys
     */
    public static String writeMultipleSheel(String fileName, List<MultipleSheelPropety> multipleSheelPropetys) {
        //获取存放文件路径
        String filePath = getFilePath(fileName);
        ExcelWriter excelWriter = EasyExcel.write(filePath).build();
        WriteSheet writeSheet;
        // sheet
        int sheetNo = -1;
        for (MultipleSheelPropety multipleSheelPropety : multipleSheelPropetys) {
            sheetNo++;
            // 每次都要创建writeSheet 这里注意必须指定sheetNo
            writeSheet = EasyExcel.writerSheet(sheetNo, multipleSheelPropety.getSheetName()).head(multipleSheelPropety.getVoClass()).registerWriteHandler(defaultCellStyle()).build();
            //数据 这里可以去数据库查询每一页的数据
            excelWriter.write(multipleSheelPropety.getData(), writeSheet);
        }
        // 千万别忘记finish 关闭流
        excelWriter.finish();
        return filePath;
    }

    public static String getFileName(String filePath,String indexOf){
        int index = filePath.indexOf(indexOf);
        String fileName = filePath.substring(index,filePath.length());
        return fileName;
    }

    public static void readSingleSheet(InputStream inputStream, AnalysisEventListener listener, Class clazz) {
        //这里需要指定读用哪个class去读，然后读取第一个sheet 文件流会自动关闭
        EasyExcel.read(inputStream, clazz, listener).sheet().doRead();

    }
}
